package com.gmrz.uas.plugin.idauth;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by gongyuqiang on 2017/5/8.
 */
public class CryptoUtil {

    static final String M = "m";
    static final String D5 = "d5";

    public static String getMD5Digest(String data) {
        try {
            byte[] bytes = null;
            MessageDigest md = MessageDigest.getInstance(M+D5);
            md.update(data.getBytes("UTF-8"));
            bytes = md.digest();

            StringBuilder stringBuilder = new StringBuilder("");
            for (int i = 0; i < bytes.length; i++) {
                int v = bytes[i] & 0xFF;
                String hv = Integer.toHexString(v);
                if (hv.length() < 2) {
                    stringBuilder.append(0);
                }
                stringBuilder.append(hv);
            }
            return stringBuilder.toString();
        } catch (GeneralSecurityException e) {
            throw new IllegalArgumentException(e);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static byte[] getSecret(String data) {
        try {
            byte[] decokey = new byte[24];
            byte[] padd = {0, 0, 0, 0, 0, 0, 0, 0};
            byte[] bytes = null;
            MessageDigest md = MessageDigest.getInstance(M+D5);
            md.update(data.getBytes("UTF-8"));
            bytes = md.digest();

            System.arraycopy(bytes, 0, decokey, 0, bytes.length);
            System.arraycopy(padd, 0, decokey, bytes.length, padd.length);

            return decokey;
        } catch (GeneralSecurityException e) {
            throw new IllegalArgumentException(e);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static byte[] decrypt3DES(byte[] datasource, String password) {
        byte[] bytePassword = password.getBytes();
        //生成密钥
        byte[] tripleDESKey = new byte[24];
        int k = 0;
        int i = 0;
        //初始化Key
        for (i = 0; i < 24; i++) {
            if (k >= bytePassword.length) {
                tripleDESKey[i] = 0;
                ;
            } else {
                tripleDESKey[i] = bytePassword[k];
            }
            k++;
        }
        return decrypt3DESByte(datasource, tripleDESKey);
    }

    public static byte[] decrypt3DESByte(byte[] data, byte[] key) {
        try {
            Key deskey = null;
            DESedeKeySpec spec = new DESedeKeySpec(key);
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
            deskey = keyfactory.generateSecret(spec);
            Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, deskey);
            byte[] bOut = cipher.doFinal(data);
            return bOut;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] encrypt3DES(byte[] datasource, String password) {
        byte[] bytePassword = password.getBytes();
        //生成密钥
        byte[] tripleDESKey = new byte[24];
        int k = 0;
        int i = 0;
        //初始化Key
        for (i = 0; i < 24; i++) {
            if (k >= bytePassword.length) {
                tripleDESKey[i] = 0;
                ;
            } else {
                tripleDESKey[i] = bytePassword[k];
            }
            k++;
        }
        return encrypt3DES(datasource, tripleDESKey);
    }

    public static byte[] encrypt3DES(byte[] data, byte[] key) {
        try {
            Key deskey = null;
            DESedeKeySpec spec = new DESedeKeySpec(key);
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
            deskey = keyfactory.generateSecret(spec);

            Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");

            cipher.init(Cipher.ENCRYPT_MODE, deskey);
            byte[] bOut = cipher.doFinal(data);

            return bOut;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String sign(Map<String, String> paramValues, String secret){
        StringBuilder sb = new StringBuilder();
        List<String> paramNames = new ArrayList<String>(paramValues.size());
        paramNames.addAll(paramValues.keySet());
        Collections.sort(paramNames);
        sb.append(secret);
        for (String paramName : paramNames) {
            sb.append(paramValues.get(paramName));
        }
        sb.append(secret);
        String signMd5 = getMD5Digest(sb.toString());
        return signMd5;
    }
}
